﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using jaysJourney_v01.Common;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using System.Diagnostics;

namespace jaysJourney_v01.Utils.Output
{
    public class MessageManager
    {
        /**
         * MEMBER VARIABLES
         * */

        // From Parent

        private JaysJourneyMain game;

        // Common

        private SpriteBatch mainSpriteBatch;
        private SpriteFont textFont;

        // Messages

        private List<Message> messageList;

        private const int maxVisibleTime = 5000; // Millisecs
        private const int messageWidth = 300; // pixel
        private const int padding = 20; // pixel
        private const int pxPerChar = 11;

        private int numCharPerLine; // calculated characters per Line

        // Textures

        private Texture2D bgMsg;
        private Texture2D bgMsgError;

        //levelup animation
        private FrameAnimator levelupAnimation;
        

        /**
         * METHODS
         * */

        // Constructor

        public MessageManager(JaysJourneyMain game)
        {
            // game
            this.game = game;
            this.messageList = new List<Message>();

            // load
            this.mainSpriteBatch = this.game.mainSpriteBatch;
            this.textFont = game.Content.Load<SpriteFont>(@"Fonts\Segoe UI Mono");

            this.bgMsg = game.Content.Load<Texture2D>(@"Textures\Interface\msg_bg");
            this.bgMsgError = game.Content.Load<Texture2D>(@"Textures\Interface\msg_error_bg");

            // calc
            this.numCharPerLine = (messageWidth - (2 * padding)) / pxPerChar;
            Debug.WriteLine(this.numCharPerLine);

            //animation
            this.levelupAnimation = new FrameAnimator(mainSpriteBatch, "levelup", 25, 94, false, false, game);
        }

        // MAIN UPDATE

        public void update(GameTime gameTime)
        {
            foreach(Message msg in messageList)
            {
                msg.update(gameTime); // update msg
                if (msg.getAlpha() <= 0)
                {
                    messageList.Remove(msg); // msg dies
                    break;
                }
            }
        }

        // draw Message

        public void draw(GameTime gameTime)
        {
            int yPos = 0;

            for (int i = 0; i < messageList.Count; i++)
            {
                // draw bg
                if (this.messageList[i].isErrMsg()) this.mainSpriteBatch.Draw(this.bgMsgError, new Rectangle(game.GraphicsDevice.Viewport.Width - messageWidth, yPos, messageWidth, messageList[i].getMsgHeight()), Color.White * messageList[i].getAlpha());
                else this.mainSpriteBatch.Draw(this.bgMsg, new Rectangle(game.GraphicsDevice.Viewport.Width - messageWidth, yPos, messageWidth, messageList[i].getMsgHeight()), Color.White * messageList[i].getAlpha());

                // draw txt
                for (int j = 0; j < messageList[i].getMessage().Count; j++)
                {
                    this.mainSpriteBatch.DrawString(this.textFont, messageList[i].getMessage()[j], new Vector2(game.GraphicsDevice.Viewport.Width - messageWidth + padding, yPos + padding + (textFont.LineSpacing * j)), Color.White * messageList[i].getAlpha());
                }

                yPos += messageList[i].getMsgHeight() + 4;
            }

            levelupAnimation.animate(gameTime, new Vector2((this.game.GraphicsDevice.Viewport.Width / 2) - 475, (this.game.GraphicsDevice.Viewport.Height / 3) - 225));
           
        }

        // add message

        public void addMessage(String message, bool isError)
        {
            // calc array
            List<String> msgArray = new List<String>();

            // fill array
            int curPos = 0;
            int i = 0;
            while(curPos <= message.Length)
            {
                if (curPos + this.numCharPerLine >= message.Length) { msgArray.Add(message.Substring(curPos, message.Length - curPos)); curPos += this.numCharPerLine; } // last column
                else
                {
                    msgArray.Add(message.Substring(curPos, this.numCharPerLine));
                    curPos += this.numCharPerLine;

                    while (msgArray[i][msgArray[i].Length - 1] != ' ') // divided a word
                    {
                        msgArray[i] = msgArray[i].Remove(msgArray.Last().Length - 1);
                        curPos--;
                    }
                }

                msgArray[i].Trim(); // remove space at col-beginning
                i++;
            }


            // calc boxHeight
            int messageHeight = 2 * padding + (this.textFont.LineSpacing * msgArray.Count);

            // add msg to list
            messageList.Add(new Message(maxVisibleTime, messageHeight, msgArray, isError));
        }

        // isListEmpty

        public bool isListEmpty()
        {
            if (this.messageList.Count != 0) return false;
            if (!this.levelupAnimation.hasFinished()) return false;
            return true;
        }

        public void playLevelUpAnimation()
        {
            this.levelupAnimation.reset();
            this.levelupAnimation.play();
        }
    }
}
